package com.logic.landseaserver.service.impl;

import java.util.*;

import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.common.LandseaErrorMessageEnum;
import com.logic.landseaserver.common.enums.ExpensesStatusEnum;
import com.logic.landseaserver.common.enums.RoomStatusCodeEnum;
import com.logic.landseaserver.common.exception.LandseaException;
import com.logic.landseaserver.common.util.ConstantChar;
import com.logic.landseaserver.common.util.DateUtil;
import com.logic.landseaserver.common.util.LandSeaUtil;
import com.logic.landseaserver.domain.*;
import com.logic.landseaserver.persistence.read.*;
import com.logic.landseaserver.persistence.write.CheckListWriteMapper;
import com.logic.landseaserver.persistence.write.ExpensesWriteMapper;
import com.logic.landseaserver.persistence.write.RoomWriteMapper;
import com.logic.landseaserver.service.IOffrentPreBill;
import com.logic.landseaserver.ws.dto.*;
import com.logic.landseaserver.ws.response.CheckFeeOutResp;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.logic.common.exception.BusinessException;
import com.logic.common.security.SecurityUtils;
import com.logic.common.util.QueryUtil;
import com.logic.landseaserver.persistence.write.CheckFeeListWriteMapper;
import com.logic.landseaserver.service.ICheckFeeListService;


/**
 * @Author: jack
 * @Date: 2017/6/16
 * @Description: 交割费用单实现类
 */
@Service
public class CheckFeeListServiceImpl implements ICheckFeeListService {

	@Autowired
	private CheckFeeListWriteMapper checkFeeListWriteMapper;

	@Autowired
	private CheckFeeListReadMapper checkFeeListReadMapper;

	@Autowired
	private IOffrentPreBill offrentPreBillService;

	@Autowired
	private ContractReadMapper contractReadMapper;

	@Autowired
	private ExpensesReadMapper expensesReadMapper;

	@Autowired
	private CheckListReadMapper checListReadMapper;

	@Autowired
	private CheckListWriteMapper checkListWriteMapper;

	@Autowired
	private ExpensesWriteMapper expensesWriteMapper;

	@Autowired
	private RoomReadMapper roomReadMapper;

	@Autowired
	private RoomWriteMapper roomWriteMapper;

	@Override
	public void delete(String arg0) throws BusinessException {

	}

	@Override
	public CheckFeeListDTO getCheckFeeListDitail(Integer contractId) {
		CheckFeeListDTO checkList = checkFeeListReadMapper.getCheckListDetail(contractId);
		return checkList;
	}

	@Override
	public int insertCheckFeeList(CheckFeeListDTO checkFeeListDTO) throws BusinessException{
		int activityInt = 0;//唯一性验证
		CheckFeeList checkList = new CheckFeeList(); 
		setCheckFeeListByCheckListDTO(checkList,checkFeeListDTO);
		checkList.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());//调用版本等信息
		checkFeeListWriteMapper.insertSelective(checkList);
		return activityInt;
	}

	@Override
	public int insert(Object arg0) throws BusinessException {
		return 0;
	}

	@Override
	public List<?> query(QueryUtil arg0) {
		return null;
	}

	@Override
	public void update(Object arg0) throws BusinessException {

	}

	@Override
	public Boolean validate(Object arg0) throws BusinessException {
		return null;
	}

	@Override
	public Boolean validateForDelete(Object arg0) throws BusinessException {
		return null;
	}

	@Override
	public Boolean validateForInsert(Object arg0) throws BusinessException {
		return null;
	}

	@Override
	public Boolean validateForUpdate(Object arg0) throws BusinessException {
		return null;
	}

	@Override
	public void editCheckFeeList(CheckFeeListDTO checkFeeListDTO) throws BusinessException {
		CheckFeeList checkList = checkFeeListReadMapper.selectByPrimaryKey(checkFeeListDTO.getId());
		setCheckFeeListByCheckListDTO(checkList,checkFeeListDTO);
		checkList.updateCommonInfo(SecurityUtils.getCurrentLogin().getUserId());//调用版本等信息
		checkFeeListWriteMapper.updateByPrimaryKeySelective(checkList);
	}

	@Override
	public void deleteCheckFeeList(Integer id) throws BusinessException {

	}

	//通过orderDTO创建order
	public void setCheckFeeListByCheckListDTO(CheckFeeList checkList ,CheckFeeListDTO checkListDTO){
		if(!StringUtils.isEmpty(checkListDTO.getId()))
		{
			checkList.setId(checkListDTO.getId());
		}
		if(!StringUtils.isEmpty(checkListDTO.getContractId()))
		{
			checkList.setContractId(checkListDTO.getContractId());
		}
		if(!StringUtils.isEmpty(checkListDTO.getType()))
		{
			checkList.setType(checkListDTO.getType());
		}
		if(!StringUtils.isEmpty(checkListDTO.getInDate()))
		{
			checkList.setInDate(checkListDTO.getInDate());
		}
		if(!StringUtils.isEmpty(checkListDTO.getConsumptionEnd()))
		{
			checkList.setConsumptionEnd(checkListDTO.getConsumptionEnd());
		}
		if (null != checkListDTO.getCheckType())
		{
		    checkList.setCheckType(checkListDTO.getCheckType());
		}
	}

	@Override
	public Object get(Integer arg0) throws BusinessException {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public CheckFeeOutResp queryEndAndLastFees(Integer contractId) throws LandseaException {
		//查询该合同是否存在
		Contract contract = contractReadMapper.selectByPrimaryKey(contractId);
		if (contract.getDeleted()) {
			throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACT_IS_NULL);
		}
		CheckFeeOutResp resp = new CheckFeeOutResp();
		List<CheckFeeOutDTO> checkFees = new ArrayList<>();
		Map<String, Object> queryParam = new HashMap<String, Object>();
		queryParam.put("contractId", contractId);
		queryParam.put("checkType", LandeaConstants.CheckType.UN_RENT);
		// 获取费用交割单详情
		List<CheckFeeListDTO> feeList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
		//获取上次缴费截止日用量
		List<BillDetail> billDetails = offrentPreBillService.queryLastPayBill(contractId);
		queryParam.put("checkType",LandeaConstants.CheckType.IN_COMING);
		List<CheckFeeListDTO> feeInList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
		if(feeInList==null){
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_FEELIST_ERROR);
		}
		if(feeList!=null){
			for(CheckFeeListDTO dto:feeList){
				String feeType = dto.getType();
				CheckFeeOutDTO checkDto =new CheckFeeOutDTO();
				checkDto.setFeeType(dto.getType());
				checkDto.setFeeTypeName(dto.getTypeName());
				checkDto.setReadMeterDateEnd(DateUtil.getInstence().convertDate(dto.getInDate()));
				checkDto.setConsumptionEnd(dto.getConsumptionEnd());
				//获取上一次用量
				Optional<BillDetail> billDt =billDetails.stream().filter(e -> e.getType().equals(feeType)).findFirst();
				Expenses lastEx= null;
				String feeStartTime = null;
				//上期存在
				if(billDt.isPresent()){
					feeStartTime=DateUtil.getInstence().convertDate(billDt.get().getDateEnd());
					HashMap qMap=new HashMap();
					qMap.put("roomId",contract.getRoomId());
					qMap.put("status", ExpensesStatusEnum.ES3.getCode());
					qMap.put("type",feeType);
					qMap.put("inDate",feeStartTime);
					lastEx = expensesReadMapper.querExpenses(qMap);
				}else{
					//查入住单
					Optional<CheckFeeListDTO> inFee =feeInList.stream().filter(e -> e.getType().equals(feeType)).findFirst();
					feeStartTime = DateUtil.getInstence().convertDate(inFee.get().getInDate());
					if(inFee.isPresent()){
						lastEx = new Expenses();
						lastEx.setDegree(inFee.get().getConsumptionEnd());
					}
				}
				if(lastEx!=null){
					checkDto.setReadMeterDateLast(feeStartTime);
					checkDto.setConsumptionLast(lastEx.getDegree());
					checkDto.setConsumption(LandSeaUtil.get2Double(dto.getConsumptionEnd()-lastEx.getDegree()));
				}else{
					continue;
				}
				checkFees.add(checkDto);
			}
		}else{
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_FEELIST_OUT_ERROR);
		}
		resp.setCheckFees(checkFees);
		return resp;
	}

	/**
	 *
	 * @param contractId B合同id
	 * @throws LandseaException
     */
	@Override
	public void synFeeList(Integer contractId) throws LandseaException {
		Integer userId  = SecurityUtils.getCurrentLogin().getUserId();
		//查询该合同是否存在
		Contract contract = contractReadMapper.selectByPrimaryKey(contractId);
		if (contract == null) {
			throw LandseaException.createException(LandseaErrorMessageEnum.CONTRACT_IS_NULL);
		}
		//获取B合同的入住单
		Map<String,Object> bMap = new HashMap<String,Object>();
		bMap.put("contractId", contractId);
		bMap.put("checkType", LandeaConstants.CheckType.IN_COMING);
		List<CheckFeeListDTO> feeBInList = checkFeeListReadMapper.selectByContractIdAndCheckType(bMap);
		if(feeBInList.size()>0){
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_CHECKFILE_IN_EXIST);
		}
		Map<String,Object> queryParam = new HashMap<String,Object>();
		queryParam.put("contractId", contract.getOriginalCId());
		queryParam.put("checkType", LandeaConstants.CheckType.UN_RENT);
		//获取A合同的退房交割单
		List<CheckFeeListDTO> feeOutList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
		queryParam.put("checkType", LandeaConstants.CheckType.IN_COMING);
		//获取A合同的入住交割单
		List<CheckFeeListDTO> feeInList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
		//获取A合同的入住交割文件
		CheckList checkInFile = checListReadMapper.selectByContractIdAndType(queryParam);
		if(feeInList.size()==0){
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_FEELIST_IN_ERROR);
		}
		if(checkInFile==null){
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_CHECKFILE_IN_ERROR);
		}
		if(CollectionUtils.isEmpty(feeOutList)){
			throw LandseaException.createException(LandseaErrorMessageEnum.OFFRENT_CHECKIN_FEELIST_OUT_ERROR);
		}

		List<CheckFeeList> checkFeeLists = new ArrayList<>();
		for(CheckFeeListDTO dto :feeOutList){
			CheckFeeList checkFee = new CheckFeeList();
			checkFee.setContractId(contractId);
			checkFee.setType(dto.getType());
			checkFee.setInDate(dto.getInDate());
			checkFee.setConsumptionEnd(dto.getConsumptionEnd());
			checkFee.setCheckType(LandeaConstants.CheckType.IN_COMING);
			checkFeeLists.add(checkFee);
		}
		checkFeeListWriteMapper.insertList(checkFeeLists);
		//如果是转转合同
		if(contract.getRentType()!=null && contract.getRentType().equals(LandeaConstants.ReRentType.CHANGE)){
			Room room = new Room();
			room.setId(contract.getRoomId());
			room.setSigned(true);
			room.setAppendStatus(RoomStatusCodeEnum.LRB3.getCode());
			room.updateCommonInfo(userId);
			roomWriteMapper.updateByPrimaryKeySelective(room);
		}else{
			CheckList checkList  = new CheckList();
			checkList.setContractId(contractId);
			checkList.setCheckinFiles(checkInFile.getCheckinFiles());
			checkList.setConventionFiles(checkInFile.getConventionFiles());
			checkList.setComments(checkInFile.getComments());
			checkList.setUserId(checkInFile.getUserId());
			checkList.setCheckType(LandeaConstants.CheckType.IN_COMING);
			checkList.updateCommonInfo(userId);
			checkListWriteMapper.insertSelective(checkList);
		}
	}

	@Override
	public void sysFeeListToExpenses(Integer contractId, Integer checkType) {
		Map<String,Object> queryParam = new HashMap<String,Object>();
		//查询换转续合同
		ContractDTO contractB = contractReadMapper.queryContractDetail(contractId);
		if(contractB!=null){
			queryParam.put("contractId", contractB.getOriginalCId());
			queryParam.put("checkType", checkType);
			Room room =roomReadMapper.selectByPrimaryKey(contractB.getRoomId());
			List<CheckFeeListDTO> feeList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
			Integer userId = SecurityUtils.getCurrentLogin().getUserId();

			if(feeList.size()>0){
				List<Expenses> expensesList = new ArrayList<>();
				for(CheckFeeListDTO dto:feeList){
					Expenses expenses = new Expenses();
					expenses.setPrjId(contractB.getProjectId());
					expenses.setPrjName(contractB.getProjectName());
					expenses.setRoomId(contractB.getRoomId());
					expenses.setBuildNum(room.getBuildNum());
					expenses.setUnitNum(room.getUnitNum());
					expenses.setFloorNum(room.getFloorNum());
					expenses.setHouseNum(room.getHouseNum());
					expenses.setType(dto.getType());
					expenses.setDegree(dto.getConsumptionEnd());
					expenses.setReadMeterTime(dto.getInDate());
					expenses.setStatus(ExpensesStatusEnum.ES3.getCode());
					expenses.setSource(0);//手抄
					expenses.setComments(ConstantChar.sys_checkfees_to_expenese);
					expenses.updateCommonInfo(userId);
					expensesList.add(expenses);
				}
				expensesWriteMapper.insertBatch(expensesList);
			}
		}

	}

	@Override
	public void deleteSysFeeListToExpenses(Integer contractId, Integer checkType) {
		Map<String,Object> queryParam = new HashMap<String,Object>();
		queryParam.put("contractId", contractId);
		queryParam.put("checkType", checkType);
		ContractDTO contract = contractReadMapper.queryContractDetail(contractId);
		List<CheckFeeListDTO> feeList = checkFeeListReadMapper.selectByContractIdAndCheckType(queryParam);
		if(feeList.size()>0){
			for(CheckFeeListDTO dto:feeList){
				HashMap deleteMap = new HashMap();
				deleteMap.put("roomId",contract.getRoomId());
				deleteMap.put("type",dto.getType());
				deleteMap.put("inDate",dto.getInDate());
				deleteMap.put("status",ExpensesStatusEnum.ES3.getCode());
				deleteMap.put("comments",ConstantChar.sys_checkfees_to_expenese);
				deleteMap.put("source",0);
				expensesWriteMapper.deleteByQueryMap(deleteMap);
			}
		}
	}

}
